package org.zjt.agent.runtime.classbyte;

import javassist.*;
import org.zjt.agent.runtime.reloader.ClassFileReloader;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Optional;

/**
 * Description:
 *
 * @author juntao.zhang
 * Date: 2018-10-24 3:31 PM
 * @see
 */
public class JavassistClassGenerator {


    public Optional<byte[]> reconstruct(byte[] classByte){
        try{
            CtClass ctClass = ClassPool.getDefault().makeClassIfNew(new ByteArrayInputStream(classByte));

            //已经被修改过，现在是冻结状态
            if (!ctClass.isFrozen()){
                CtMethod method = ctClass.getDeclaredMethod("list");
                method.insertBefore("System.out.println(\"agent insert method before!\");");
                method.insertAfter("System.out.println(\"agent insert method after!\");");
                return Optional.ofNullable(ctClass.toBytecode());
            }
            return Optional.ofNullable(classByte);
        }catch (Throwable e){
            e.printStackTrace();
        }
        return Optional.ofNullable(classByte);
    }



    public static void main(String[] args) throws Exception {
        byte[] bytes = ClassFileReloader.file2Byte("/Users/juntao.zhang/dev/workspace/myproject/java-basic/target/classes/org/zjt/javassist/Student.class");
        CtClass ctClass = ClassPool.getDefault().makeClass(new ByteArrayInputStream(bytes));
        ctClass.defrost();
        CtMethod method = ctClass.getDeclaredMethod("execute");
        method.insertBefore("System.out.println(\"agent insert method before!\");");
        method.insertAfter("System.out.println(\"agent insert method after!\");");
        byte[] bytes1 = ctClass.toBytecode();



        ctClass = ClassPool.getDefault().makeClassIfNew(new ByteArrayInputStream(bytes));
        if (!ctClass.isFrozen()){
            method = ctClass.getDeclaredMethod("execute");
            method.insertBefore("System.out.println(\"agent insert method before!\");");
            method.insertAfter("System.out.println(\"agent insert method after!\");");
            bytes1 = ctClass.toBytecode();
        }

    }


}
